namespace map2D {
	/**场景基类，编写通用的场景地图渲染和角色创建销毁的基础方法*/
export class SceneManagerBase implements IKeyBoardObject,IScene
	{		
		public roleQueueMgr:RoleQueueManager;		
		public mapPosChanged:boolean;
		public sceneLogic:ISceneLogicBase;
		public _playBackRate:number;
		public _paused:boolean;
		protected _pauseTime:number;
		protected _pauseStartTime:number;
		/**上一帧时间*/public lastTimeTick:number;
		/**前后帧时间差*/public timeDelta:number;
		public ignoreBarrier:boolean;
		protected _mapRedrawListener:Listener;
		protected _mapViewRole:IRole;
		protected _tempMapViewRole:IRole;
		protected _mapIsMoving:number;
		protected _moveMapCallBack:Function;
		protected _thisMoveMapObj:any;
		protected _moveXYZ:number[];	
		public constructor(gameContainer:GYSprite,sceneLayer:GYSprite,sceneBaseWidth:number,sceneBaseHeight:number)
		{
			let s = this;	
			s.roleQueueMgr = new RoleQueueManager(s);
			// s._sceneRoleVec = [];
			s._playBackRate = 1;
			s._depthArr = [];
			s._moveXYZ = [];		
			s._yIndexTime = 0;
			s._runRect = new Rectangle(400,300,300,300);
			s._visibleRect = new Rectangle;
			s._mapMinX = -Number.MAX_VALUE;
			s._mapMaxX = Number.MAX_VALUE;
			s._mapMinY = -Number.MAX_VALUE;
			s._mapMaxY = Number.MAX_VALUE;
			s._mapRedrawListener = new Listener;			
			
			s._areaArr = [];
			s._areaYArr = [];
			s._mapMoveListener = new Listener;
			// s._sceneRoleStsDict = {};
			s._sceneScale = 1;			
			s._gameContainer = gameContainer;
			s._sceneLayer = sceneLayer;			
			
			s._targetScale = 0;
			s._scaleStep = 0.005;
			s._scaleKeepTime = 0.8;
			s._sceneTouchabled = GameManager.debug;
			
			s.barrier = new Barrier;						
			s._mapBricker = new MapBricker(s);
			s._mapBackBricker = new MapBricker(s);
			s.setSceneSize(sceneBaseWidth,sceneBaseHeight,1);
		}
		/**获取默认配置，覆盖可重新写返回的默认配置，返回对象参考Default*/
		public getDefault():Default
		{
			let s= this;
			if(s._default == null)
				s._default = new Default;
			return s._default;
		}
		public setMyPlayer(player:IMyPlayer):void
		{
			let s= this;
			s._myPlayer = player;
		}		
		public setSceneSize(w:number,h:number, scale:number = 1):void
		{let s = this;
			w = Math.floor(w);
			h = Math.floor(h);
			s._sceneLayer.width = s._sceneBaseWidth = w;
			s._sceneLayer.height = s._sceneBaseHeight = h;
			s._mapBackBricker.setSceneSize(w,h);
			s._mapBricker.setSceneSize(w,h);
			s.setScale(scale, false);
			s.setMapXY(s._mapX, s._mapY, true);
		}
		public setMapXY(toX:number,toY:number, reset:boolean = false):void
		{let s = this;
			if(s._mapX == toX && s._mapY == toY && !reset)return;
			
			s._mapX = (toX >> 0);			
			s._mapY = (toY >> 0);
			s.mapPosChanged = true;
			s._mapRight = s._mapX + s._sceneWidth + 100;
			s._mapBottom = s._mapY + s._sceneHeight + 100;
			// s._gameManager.gameWorld.sceneX = s._mapX * s._sceneScale;
			// s._gameManager.gameWorld.sceneY = s._mapY * s._sceneScale;
			s.setSceneElement(s._mapX, s._mapX + s._sceneWidth,s._mapY, s._mapY + s._sceneHeight,reset);
			if(s._isScaleChange)
			{
				s._gameContainer.scale(s._sceneScale, s._sceneScale);				
				s._isScaleChange = false;
			}
			s._mapMoveListener.dataChange();
			s._mapRedrawListener.dataChange();				
		}
		// public resetAllRoles():void
		// {let s = this;
		// 	var len:number;
		// 	s.delSceneElement();
		// 	len = s._sceneRoleVec.length;
		// 	while(--len>-1)
		// 	{
		// 		s._sceneRoleVec[len].reset(s._sceneRoleVec[len].cfg);
		// 	}
		// }
		/**设置场景视图区域
		 * @param l 左边界
		 * @param r 右边界
		 * @param t 上边界
		 * @param b 下边界
		 * @param reset 是否重置，默认false，否则不会进行区域是否变更的判断，直接把视图内容重新刷新
		*/
		public setSceneElement(l:number,r:number,t:number=0,b:number=1000,reset:boolean=false):void
		{let s = this;
			var size:number;
			var arr:any[];			
			var i:number,len:number,j:number,len2:number,k:number,len3:number;
			var key:string;
			var change1:boolean,change2:boolean;
			var mapName:string,backName:string,rowName:string;
			let mapX:number,mapY:number;
			let col:number,row:number,mapCol:number,mapRow:number,innerCol:number,innerRow:number;//图集行列索引，地图砖块行列索引，图集内部行列
			let back_mapY:number,back_mapX:number,back_r:number,back_l:number,back_col:number,back_mapCol:number,back_innerCol:number;//背景图集行列索引，地图砖块行列索引，图集内部行列
			let absX:number,absY:number;
			if(s._sceneCfg == null)return;
			size = s._mapAreaSize;
			mapX = l;
			mapY = t;
			// offX = l % size;
			// offY = t % size;						
			back_mapY = t*s._backScaleY|0;			
			back_mapX = l*s._backScaleX|0;						
			back_l = Math.floor(back_mapX / size);
			back_r = back_l + r - l;
			l = Math.floor(l / size);
			r = Math.floor(r / size);
			t = Math.floor(t / size);
			b = Math.floor(b / size);
			change1 = l != s._visibleRect.left || r != s._visibleRect.right;
			change2 = t != s._visibleRect.top || b != s._visibleRect.bottom;
			mapName = s._mapName;		
			backName = s._backMapName;				
			s._mapBackBricker.brickCheck();
			if(backName)
			{
				len3 = back_r + 1;		
				for(k = back_l;k<len3;++k)
				{
					back_col = k % s._maxAreaX;
					back_col = back_col < 0?back_col + s._maxAreaX:back_col;						
					mapCol = back_col / s._mapPCol | 0;
					innerCol = back_col % s._mapPCol;		
					absX = k*size;					
					s._mapBackBricker.brickDraw(absX - back_mapX,-back_mapY,absX,0,innerCol,0,mapCol,0);
				}
			}			

			s._mapBricker.brickCheck();
			var t1:number,t2:number;
			if(s._sceneCfg.areaRoles && (change1 || change2 || reset))
			{
				// mapName = s._sceneCfg.sceneInfo.mapName;
				len = b + 1;
				len3 = r + 1;
				s._areaArr.length = 0;
				s._areaYArr.length = 0;
				for(i=t;i<len;++i)
					s._areaYArr.push(i);
				for(k = l;k<len3;++k)
					s._areaArr.push(k);
				for(i=t;i<len;++i)
				{
					row = i % s._maxAreaY;	
					row = row < 0?row + s._maxAreaY:row;					
					mapRow = row / s._mapPRow | 0;
					innerRow = row % s._mapPRow;					
					for(k = l;k<len3;++k)
					{
						col = k % s._maxAreaX;
						col = col < 0?col + s._maxAreaX:col;						
						mapCol = col / s._mapPCol | 0;
						innerCol = col % s._mapPCol;		
						absX = k*size;
						absY = i*size;
						s._mapBricker.brickDraw(absX - mapX,absY - mapY,absX,absY,innerCol,innerRow,mapCol,mapRow);
						if(reset || k < s._visibleRect.left || k > s._visibleRect.right || i < s._visibleRect.top || i > s._visibleRect.bottom)
						{							
							key = row + "_" + col;
							if(s._sceneCfg.areaRoles[key] == null)continue;
							arr = s._sceneCfg.areaRoles[key];
							len2 = arr.length;
							for(j=0;j<len2;++j)
							{
								let roleCfg:any = s._sceneCfg.sceneRoles[arr[j]];
								if(roleCfg)
									s.createRoleByCfg(null, roleCfg, roleCfg.roleType, roleCfg.sts, roleCfg.createDir, roleCfg.absX, roleCfg.absY);
								else
								{
									console.warn("找不到地图元素：" + arr[j] + "，区域："+key);
								}
							}
							
						}
					}
				}
				s._visibleRect.left = l;
				s._visibleRect.right = r;
				s._visibleRect.top = t;
				s._visibleRect.bottom = b;
				s.delSceneElement();
//				trace("bodys:"+GameManager.game.gameWorld.world.GetBodyCount()+"-"+LayerManager.getInstance().roadLay.numChildren,_visibleRect.left,_visibleRect.right,_areaArr,_areaYArr);
			}
			else
			{				
				len = b + 1;
				len3 = r + 1;				
				for(i=t;i<len;++i)
				{
					row = i % s._maxAreaY;	
					row = row < 0?row + s._maxAreaY:row;					
					mapRow = row / s._mapPRow | 0;
					innerRow = row % s._mapPRow;				
					for(k = l;k<len3;++k)
					{
						col = k % s._maxAreaX;
						col = col < 0?col + s._maxAreaX:col;						
						mapCol = col / s._mapPCol | 0;
						innerCol = col % s._mapPCol;									
						absX = k*size;
						absY = i*size;
						s._mapBricker.brickDraw(absX - mapX,absY - mapY,absX,absY,innerCol,innerRow,mapCol,mapRow);
					}					
				}
			}			
			s._mapBackBricker.render();
			s._mapBricker.render();				
		}		
		/**获取地图切片纹理
		 * @param mapName 地图图片名称
		 * @param mapCol 列索引
		 * @param mapRow 列索引
		*/
		public getBrickTexture(brick:Brick,mapCol:number,mapRow:number):void
		{
			let s = this;			
			let url:string = `${ghost.Conf.mapAlias}${s.mapName}/${mapRow}_${mapCol}.${s._brickExt}`;
			brick.url = url;
			Main.instance.myLoader.loadPath(url,brick.resLoadComp, brick, GYLoader.TYPE_IMAGE);
				
		}
		/**设置角色状态，当sts设置为-1时，清除状态为1的状态记录，为其他状态则不受影响，1表示已经出生 2表示永久死亡*/
		// public setRoleSceneSts(id:number,sts:number=-1):void
		// {let s = this;
		// 	if(id == null)return;
		// 	if(sts == -1)
		// 	{
		// 		if(s._sceneRoleStsDict[id] == 1)
		// 			delete s._sceneRoleStsDict[id];
		// 		return;
		// 	}				
		// 	s._sceneRoleStsDict[id]=sts;
		// }
		public createRoleByCfg(owner:map2D.IRole,cfg:any,roleType:number=0,createSts:number=0,createDir:number=0,x:number=0,y:number=0,sceneParam:any=null):map2D.IRole
		{
			return null;
		}
		protected delSceneElement():void
		{
			// let s = this;
			// var j:number,len2:number;
			// var delRole:IRole;
			// len2 = s._sceneRoleVec.length;
			// if(len2 == 0)return;
			// while(--len2>-1)
			// {
			// 	delRole = s._sceneRoleVec[len2];
			// 	if(s.isAreaInVisRect(delRole.areaRowMin, delRole.areaRowMax, delRole.areaColMin, delRole.areaColMax))continue;				
			// 	delRole.clear();
			// 	s._sceneRoleVec.splice(len2,1);
			// }
		}	
		/**添加一个角色到场景，根据roleListType添加到场景不同的分组列表，默认只有-1这个分组，可定义不同编号分组，添加到对应数组，但是切记removeFromSceneVec方法里面也要进行重载，移除时根据角色的roleListType的类型从列表中相应移除
		 * @param r 角色
		 * @param type 类型
		*/
		public addToSceneVec(r:IRole):void
		{
			// let s = this;
			// let arr:IRole[];
			// if(-1 == r.roleListType)		
			// {
			// 	s._sceneRoleVec.push(r);							
			// }	
		}
		/**从场景的角色列表移除一个角色，默认列表是sceneRoleVec，roleListType类型-1，
		 * @param r 角色
		 * @param type 类型
		*/
		public removeFromSceneVec(r:IRole):void
		{			
			// let arr:IRole[];
			// let s= this;			
			// if(-1 == r.roleListType)
			// {
			// 	arr = s._sceneRoleVec;
			// 	if(arr)
			// 		arr.splice(r.seq, 1);
			// }
		}
		/** 寻路*/
		public findPath(fromX:number,fromY:number,toX:number,toY:number,trackArr:any[],trackDirectionArr:any[],speed:number):number[][]
		{
			let s = this;
			let gridSize:number;
			let agl:number,disX:number,disY:number;
			let stX:number,stY:number,edX:number,edY:number,dir:number;						
			let i:number,len:number;
			let halfPI:number;
			trackDirectionArr.length = trackArr.length=0;
			if (Math.abs(toX - fromX) < 11 && Math.abs(toY - fromY) < 11)
			{				
				return trackArr;
			}
			gridSize = s.gridSize;			
			let stCol:number,stRow:number,edCol:number,edRow:number;			
			stCol=fromX / gridSize | 0;
			stRow=fromY / gridSize | 0;
			edCol=toX / gridSize | 0;
			edRow=toY / gridSize | 0;			

			if (stCol == edCol && stRow == edRow)
			{			
				trackArr.push([toX, toY]);
				if(toY == fromY)					
					trackDirectionArr.push(fromX <= toX?DirectionType.RIGHT:DirectionType.LEFT);				
				else if (toY < fromY)
				{
					if(fromX == toX)
						trackDirectionArr.push(DirectionType.UP);
					else					
						trackDirectionArr.push(fromX < toX?DirectionType.LEFT_UP:DirectionType.RIGHT_UP);
				}
				else if (toY > fromY)
				{
					if(fromX == toX)											
						trackDirectionArr.push(DirectionType.DOWN);					
					else											
						trackDirectionArr.push(fromX < toX?DirectionType.LEFT_DOWN:DirectionType.RIGHT_DOWN);										
				}				
				return;
			}
			var arr:number[] = [];
			halfPI = Math.PI/2;			
			trackArr = s.aStar.doSearch(fromX / gridSize |0, fromY / gridSize |0, toX / gridSize |0,toY / gridSize |0,trackArr);
			trackArr.reverse();
			len = trackArr.length;
			stX = fromX / gridSize | 0;
			stY = fromY / gridSize | 0;
			for(i=0;i<len;++i)
			{				
				edX = trackArr[i][0];
				edY = trackArr[i][1];
				disX = edX - stX;
				disY = edY - stY;				
				agl = disX == 0?(disY > 0?halfPI:-halfPI):Math.atan2(disY,disX);
				stX = edX;
				stY = edY;
				dir = DirectionType.getDirectorSts(agl,DirectionMode.EIGHT);
				// if(dir == DirectionType.UP || dir == DirectionType.DOWN)
				// 	trackArr[i] = (trackArr[i][1] + 0.5) * gridSize;
				// else
				// 	trackArr[i] = (trackArr[i][0] + 0.5) * gridSize;
				trackArr[i][0] = (trackArr[i][0] + 0.5) * gridSize;
				trackArr[i][1] = (trackArr[i][1] + 0.5) * gridSize;				
				trackDirectionArr.push(dir);
			}
			return trackArr;
		}
		
		/**判断区域坐标是否在可视范围内*/
		public isInVisRect(row:number,col:number):boolean
		{let s = this;
			return s._areaArr[0] <= col  && s._areaArr[s._areaArr.length - 1] >= col && s._areaYArr[0] <= row  && s._areaYArr[s._areaYArr.length - 1] >= row;				
		}
		/**判断区域是否在可视范围内*/
		public isAreaInVisRect(minRow:number,maxRow:number,minCol:number,maxCol:number):boolean
		{let s = this;
			return !(s._areaArr[0] > maxCol  || s._areaArr[s._areaArr.length - 1] < minCol || s._areaYArr[0] > maxRow || s._areaYArr[s._areaYArr.length - 1] < minRow);
		}
		public setScale(scale:number, check:boolean = true):void
		{let s = this;
			if(scale == s._sceneScale && check)return;
			var sW:number,sH:number,sX:number,sY:number;
			let def:Default = s.getDefault();
			sW = s._sceneWidth;
			sH = s._sceneHeight;
			s._sceneWidth = s._sceneBaseWidth / scale;
			s._sceneHeight = s._sceneBaseHeight / scale;
			s._sceneScale = scale;
			s._isScaleChange = true;
			s.resetRunBorder();
			s.setRunRect(s._sceneWidth * def.run_width_p, s._sceneWidth * def.run_width_p2, s._sceneHeight * def.run_height_p, s._sceneHeight * def.run_height_p2);			
		}
		private setRunRect(l:number,r:number,t:number,b:number):void
		{let s = this;
			s._runRect.left = l;
			s._runRect.right = r;
			s._runRect.top = t;
			s._runRect.bottom = b;
		}
		public setScaleTo(scale:number):void
		{let s = this;
			if(CommonUtil.loopTime - s._scaleTime < s._scaleKeepTime)return;
			if(s._targetScale == scale)return;
			if(s._targetScale == 0)
			{
				if(s._sceneScale == scale)return;
				CommonUtil.addStageLoop(s.scaleLoop,s);
			}
			s._scaleTime = CommonUtil.loopTime;
			s._targetScale = scale;
			s._scaleDir = s._targetScale > s._sceneScale?1:0;
		}
		protected stopScale(scl:number):void
		{let s = this;
			s.setScale(scl);
			CommonUtil.delStageLoop(s.scaleLoop,s);
			s._targetScale = 0;
		}
		protected scaleLoop(t:number):void
		{let s = this;
			if(s._scaleDir == 1)
			{
				if(s._sceneScale < s._targetScale)
					s.setScale(s._sceneScale + s._scaleStep);
				else				
					s.stopScale(s._targetScale);
			}
			else
			{
				if(s._sceneScale > s._targetScale)
					s.setScale(s._sceneScale - s._scaleStep);
				else				
					s.stopScale(s._targetScale);
			}
		}

		/**场景是否可触碰寻路*/
		public get sceneTouchabled():boolean
		{
			return this._sceneTouchabled;
		}
		private touchBegin(e:Laya.Event):void
		{
			let s = this;
			if(!s._sceneTouchabled)return;
			s._touchTarget = e.target;
			if(s._touchTarget == s._sceneLayer)
			{
				s._touchMapX = s._sceneLayer.mouseX;
				s._touchMapY = s._sceneLayer.mouseY;
				// GYLite.CommonUtil.addStageLoop(s.touchMapMove,s);
			}
		}
		private touchEnd(e:Laya.Event):void
		{
			let s = this;
			let toX:number,toY:number;
			if(!s._sceneTouchabled)return;
			toX = s._sceneLayer.mouseX;
			toY = s._sceneLayer.mouseY;
			if(s._touchTarget == s._sceneLayer)
			{
				// GYLite.CommonUtil.delStageLoop(s.touchMapMove,s);
				// if(!s._touchDrag)
				// {
				// 	//自动寻路到toX toY处
				// 	s._myPlayer.findPathTo(s._mapX + toX, s._mapY + toY);
				// }
				// else
				// 	s._myPlayer.setOperSts(StsType.STAND);
				s._myPlayer.setEndCoord(s._mapX + toX, s._mapY + toY);
			}
			s._touchDrag = false;
			s._touchTarget = null;
		}
		private touchMapMove(t:number):void
		{
			let s = this;
			let toX:number,toY:number;
			toX = s._sceneLayer.mouseX;
			toY = s._sceneLayer.mouseY;
			if(Math.abs(toX - s._touchMapX) > 5 || Math.abs(toY - s._touchMapY) > 5)
			{
				if(s._myPlayer.directSts > 0)return;
				let agl:number;
				agl = Math.atan2(toY - s._sceneHeight / 2, toX - s._sceneWidth / 2);
				s._myPlayer.moveDir(agl);
				s._touchDrag = true;
			}
		}	
		// /**移除角色，此方法角色内部调用，如需移除角色，请直接设置角色的idDel属性*/
		// public addDelRole(r:IRole):void
		// {let s = this;
		// 	s._delRoleVec.push(r);
		// }
		
		protected sortYIndex(a:IRole,b:IRole):number
		{
			if(a.absY < b.absY)
				return -1;
			return 1;
		}
		/**排列层级*/
		protected resetDp():void
		{
			let s= this;
			// 默认列表
			// let i:number,len:number;
			// let r:IRole;
			// len=s._sceneRoleVec.length;			
			// for (i=0; i < len; ++i)
			// {
			// 	r=s._sceneRoleVec[i];
			// 	if (r.isVisible() && r.isSceneLayer())
			// 		s._depthArr.push(r);
			// }
			if(s._depthArr.length > 0)
			{
				s._depthArr.sort(s.sortYIndex);
				let len:number;
				len = s._depthArr.length;
				while(--len>-1)				
					s._depthArr[len].setYIndex(0);								
				s._depthArr.length = 0;
			}				
		}	
		public reloadScene():void
		{
			let s= this;
			s.loadScene(s._sceneCfg);
		}
		public loadScene(cfg:Object=null):void
		{
			let s = this;
			s.clearScene();
			s.createScene(cfg);
			s.enterScene();
		}
		protected createScene(sceneCfg:any):void
		{
			let s = this;						
			s.timeTick = CommonUtil.loopTime;
			s.resetSceneConfig(sceneCfg);			
		}
		public resetSceneConfig(sceneCfg:any):boolean
		{
			let s = this;
			if(s._sceneCfg == sceneCfg)
				return false;
			if(sceneCfg)
				s._sceneCfg = sceneCfg;
			s.configSet(s._sceneCfg);			
			s.setMapXY(s._initMapX,s._initMapY,true);
			return true;
		}
		public outputCfg():any
		{
			
		}
		/**生成场景配置（暂时无用）*/
		private createMapJson(fileName:string,resKey:string=null):void
		{
			let json:any;
			let i:number,len:number,j:number,len2:number;
			let s = this;
			let arr:string[];
			let n:number,m:number;
			let stX:number,stY:number,w:number,h:number;
			json = {"file":fileName + ".png","frames":{}};
			//i 列 j 行
			len = s._maxAreaX;
			len2 = s._maxAreaY;
			arr = fileName.split("_");
			n = Number(arr[1]);//n 大区-列
			m = Number(arr[2]);//m 大区-行
			stX = 0;
			stY = 0;
			w = h = s._mapAreaSize;
			for(i=0;i<len;++i)
			{
				stX = i * w;
				for(j=0;j<len2;++j)
				{					
					stY = j	* h;				
					json.frames[i + "_" + j] = {"x":stX,"y":stY,"w":w,"h":h,"offX":0,"offY":0,"sourceW":w,"sourceH":h}
				}	
			}
			if(resKey)
				GYLoader.setDataRes(resKey + fileName,json);
		}
		public enterScene():void
		{let s = this;						
			s._rateCount = 0;
			Laya.stage.mouseEnabled = true;
			GYKeyboard.getInstance().addKeyListener(s);
			s.resume();//假设进入场景前是暂停状态要恢复场景
		}
		/**添加到深度列表，后续进行排序*/
		protected addToDepthList(list:IRole[]):void
		{
			let i:number,len:number;
			let r:IRole;
			let s= this;
			len=list.length;
			for (i=0; i < len; ++i)
			{
				r=list[i];
				if (r.isVisible() && r.isSceneLayer())
					s._depthArr.push(r);
			}	
		}		
		protected update(t:number,list:IRole[]):void
		{
			let len:number;
			let r:IRole;			
			len = list.length;
			while(--len>-1)
			{
				r=list[len];
				if(r._isDel < t)
				{	
					r.clear();					
					list.splice(len, 1);
					continue;
				}
				r.update(t,len);
			}
		}
		protected updateLater(t:number,list:IRole[]):void
		{			
			let len:number;
			len = list.length;
			while(--len>-1)				
			{
				if(list[len]._isDel < t)
					continue;
				list[len].updateLater(t,len);
			}	
		}
		protected clearList(list:IRole[]):void
		{
			let len:number;
			len = list.length;
			while(--len>-1)			
				list[len].clear();	
			list.length = 0;
		}
		/**清理场景，其他东西请在清理方法执行前进行清理*/
		public clearScene():void
		{let s = this;
			s._mapBackBricker.clear();
			s._mapBricker.clear();
			// s.clearList(s._sceneRoleVec);			
			// s._sceneRoleStsDict = {};
			// s._myPlayer.clear();			
			s._mapX = s._mapY = -1;
			s.stopScale(1);
			s._areaArr.length = s._visibleRect.left = s._visibleRect.right = s._visibleRect.top = s._visibleRect.bottom = 0;
		}
		/**配置设置*/
		protected configSet(sceneCfg:any):void
		{let s = this;
			let cfg:any = sceneCfg.sceneInfo;
			let def:Default;
			s._mapPW = sceneCfg.atalsWidth?sceneCfg.atalsWidth:2048;
			s._mapPH = sceneCfg.atalsHeight?sceneCfg.atalsHeight:2048;
			def = s.getDefault();
			s._brickExt = cfg.ext;
			s._backScaleX = cfg.backScaleX == null?def.back_scale_x:cfg.backScaleX;
			s._backScaleY = cfg.backScaleY == null?def.back_scale_y:cfg.backScaleY;
			s._maxAreaX = cfg.maxAreaX == null?def.max_area_x:cfg.maxAreaX;
			s._maxAreaY = cfg.maxAreaY == null?def.max_area_y:cfg.maxAreaY;
			s._mapAreaSize = cfg.mapAreaSize == null?def.map_areasize:cfg.mapAreaSize;
			s._mapName = cfg.mapName;
			s._backMapName = cfg.backMapName;
			
			s._initMapX = cfg.mapInitX == null?def.map_init_x:cfg.mapInitX;
			s._initMapY = cfg.mapInitY == null?def.map_init_y:cfg.mapInitY;
			s._mapPCol = s._mapPW / s._mapAreaSize;
			s._mapPRow = s._mapPH / s._mapAreaSize;
			s._mapMinX = 0;
			s._mapMinY = 0;			
			s._mapMaxX = cfg.mapMaxX > 0?cfg.mapMaxX:(s._maxAreaX * s._mapAreaSize);
			s._mapMaxY = cfg.mapMaxY > 0?cfg.mapMaxY:(s._maxAreaY * s._mapAreaSize);
			
			
			s._gridSize = cfg.gridSize == null?def.grid_size:cfg.gridSize;
			
			if(sceneCfg.barriers == null)
			{
				sceneCfg.barriers = [];
				sceneCfg.barriers.length = s.mapGridCol*s.mapGridRow;
				sceneCfg.barriers.fill(Barrier.LAND);
			}				
			s.barrier.setBarrier(sceneCfg.barriers,[s._mapMinX,s._mapMinY,s._mapMaxX,s._mapMaxY,s.mapGridCol,s.mapGridRow],s._gridSize);
			if(s.aStar)
				s.aStar.dispose();
			s.aStar = new AStar(s, false);
			s.resetRunBorder();
		}
		/**重设行走的视图边界*/
		protected resetRunBorder():void
		{
			let s= this;
			s._runMaxX = s._mapMaxX;
			s._runMaxY = s._mapMaxY;
			s._runMinX = s._mapMinX;
			s._runMinY = s._mapMinY;			
			let w:number,h:number;
			w = s._runMaxX - s._runMinX - s._sceneWidth;
			h = s._runMaxY - s._runMinY - s._sceneHeight;
			//移动边界小于屏幕显示区域时，重新调整移动边界保证地图能完全显示
			if(w < 0)
			{
				w = w >> 1;
				s._runMinX += w;
				s._runMaxX -= w;
			}
			if(h < 0)
			{
				h = h >> 1;
				s._runMinY += h;
				s._runMaxY -= h;
			}			
		}
		/**重置障碍相关配置**/
		public resetBarrier():boolean
		{
			let s= this;
			let cfg:any = s._sceneCfg.sceneInfo;
			let def:Default = s.getDefault();
			s._brickExt = s._brickExt  = cfg.brickExt?"." + cfg.brickExt:".jpg";
			s._backMapName = cfg.backMapName;
			s._mapName = cfg.mapName;
			s._maxAreaX = cfg.maxAreaX == null?def.max_area_x:cfg.maxAreaX;
			s._maxAreaY = cfg.maxAreaY == null?def.max_area_y:cfg.maxAreaY;
			s._maxAreaWidth = s._maxAreaX * s._mapAreaSize;
			s._maxAreaHeight = s._maxAreaY * s._mapAreaSize;
			s._runMinX = s._mapMinX = cfg.mapMinX > 0?cfg.mapMinX:0;
			s._runMinY = s._mapMinY = cfg.mapMinY > 0?cfg.mapMinY:0;
			s._runMaxX = s._mapMaxX = cfg.mapMaxX > 0?cfg.mapMaxX:s._maxAreaWidth;
			s._runMaxY = s._mapMaxY = cfg.mapMaxY > 0?cfg.mapMaxY:s._maxAreaHeight;
			s._mapWidth = cfg.mapWidth > 0?cfg.mapWidth:cfg.mapMaxX;
			s._mapHeight = cfg.mapHeight > 0?cfg.mapHeight:cfg.mapMaxY;
			s._gridSize = cfg.gridSize == null?def.grid_size:cfg.gridSize;
			s.barrier.setBarrier(s._sceneCfg.barriers,[s._mapMinX,s._mapMinY,s._mapMaxX,s._mapMaxY,s.mapGridCol,s.mapGridRow],s._gridSize);
			s.resetRunBorder();
			s.setMapXY(s._mapX,s._mapY, true);
			return true;
		}
		public loop(t:number):void
		{
			let s= this;		
			if(!s._paused)	
			{
				s.lastTimeTick = s.timeTick;
				s.timeTick = t - s._pauseTime;	
				s.timeDelta = s.timeTick - s.lastTimeTick;
			}
			
			t = s.timeTick;
			++s._rateCount;
			s.enterLoop(t);
			s.exitLoop(t);		
		}
		protected exitLoop(t:number):void
		{
			let s= this;			
			if(s._mapViewRole)					
				s.setMoveRect(s._mapViewRole);				
			s._lastTick = t;			
		}		
		protected enterLoop(t:number):void
		{
			let s= this;
			if(t - s._yIndexTime > 100)
			{				
				s.resetDp();
				s._yIndexTime = t;
			}			
		}
		/**移动画面
		 * @param x 世界坐标x
		 * @param y 世界坐标y
		 * @param z 世界坐标z
		 * @param time 用时（毫秒）默认1000
		 * @param callBack 回调
		 * @param thisObj 
		*/
		public viewMoveTo(x:number=NaN,y:number=NaN,z:number=NaN,time:number=1000,callBack:Function=null,thisObj:any=null):void
		{
			let s = this;
			if(s._mapIsMoving > 0)return;
			Laya.stage.mouseEnabled = false;
			s._mapIsMoving = 1;
			s._moveMapCallBack = callBack;
			s._thisMoveMapObj = thisObj;			
			if(x == x || y == y || z == z)
			{
				s._tempMapViewRole = s._tempMapViewRole;
				s.setMapViewRole(null);
			}				
			else
				s.setMapViewRole(s._tempMapViewRole);
			if(x == x)
				ghost.GYTween.to(s,[ghost.TweenData.getInstance("mapX",x),ghost.TweenData.getInstance("mapY",y)],time,0,s,s.viewMoveEnd);
			else
			{
				let arr:number[]=s.getMoveRect(s._myPlayer);
				ghost.GYTween.to(s,[ghost.TweenData.getInstance("mapX",arr[0]), ghost.TweenData.getInstance("mapY",arr[1])],time,0,s,s.viewMoveEnd);			
			}
			
			
		}
		protected viewMoveEnd():void
		{
			let s= this;
			if(s._mapIsMoving == 0)return;
			--s._mapIsMoving;
			if(s._mapIsMoving == 0)
			{
				Laya.stage.mouseEnabled = true;
				if(s._moveMapCallBack!=null)
				{
					let func:Function;
					let obj:any;
					func = s._moveMapCallBack;
					obj = s._thisMoveMapObj;
					s._thisMoveMapObj = s._moveMapCallBack = null;
					func.call(obj);					
				}				
			}
		}
		/**设置地图的角色视角*/
		public setMapViewRole(r:IRole):void
		{let s = this;
			s._mapViewRole = r;			
		}
		public get mapViewRole():IRole
		{
			return this._mapViewRole;
		}
		public get rateCount():number
		{
			return this._rateCount;
		}
		public get sceneID():string
		{
			return this._sceneCfg.sceneID;
		}	
		public get sceneLayer():GYSprite
		{
			return this._sceneLayer;			
		}
		
		public get gameContainer():GYSprite
		{
			return this._gameContainer;			
		}
		public set mapX(val:number)
		{let s = this;			
			s.setMapXY(val,s._mapY);
		}		

		public set mapY(val:number)
		{let s = this;			
			s.setMapXY(s._mapX, val);
		}
		public get mapX():number
		{let s = this;
			return s._mapX;
		}		

		public get mapY():number
		{let s = this;
			return s._mapY;
		}

		public get gridSize():number
		{
			return this._gridSize;
		}
		public get mapGridCol():number
		{
			let s = this;
			return Math.ceil(s._mapMaxX/s._gridSize);			
		}
		public get mapGridRow():number
		{
			let s = this;
			return Math.ceil(s._mapMaxY/s._gridSize);
		}

		// public get sceneRoleVec():IRole[]
		// {let s = this;
		// 	return s._sceneRoleVec;
		// }

		public setMoveRect(r:IRole):void
		{
			let s = this;
			if(s._mapIsMoving > 0)return;
			if(r == null)return;
			let arr:number[] = s.getMoveRect(r);
			s.setMapXY(arr[0], arr[1]);			
		}
		public getMoveRect(r:IRole):number[]
		{
			var localX:number,localY:number;
			var moveX:number,moveY:number;
			var mX:number,mY:number;
			var rX:number,rY:number;
			let s = this;
			
			rX = r.absX >> 0;
			rY = r.absY >> 0;
			localX = rX - s._mapX;
			localY = rY - s._mapY;
			if(localX > s._runRect.right)
			{
				moveX = rX - s._runRect.right;
				mX = (moveX > s._mapMaxX - s._sceneWidth)?s._mapMaxX - s._sceneWidth:moveX;
			}
			else if(localX < s._runRect.left)
			{
				moveX = rX - s._runRect.left;
				mX = moveX < s._mapMinX?s._mapMinX:moveX;
			}
			else
				mX = s._mapX;
			if(localY > s._runRect.bottom)
			{
				moveY = rY - s._runRect.bottom;
				mY = (moveY > s._mapMaxY - s._sceneHeight)?s._mapMaxY - s._sceneHeight:moveY;
			}
			else if(localY < s._runRect.top)
			{
				moveY = rY - s._runRect.top;
				mY = moveY < s._mapMinY?s._mapMinY:moveY;
			}
			else
				mY = s._mapY;
			s._moveXYZ[0] = mX|0;
			s._moveXYZ[1] = mY|0;
			// s._moveXYZ[2] = mZ|0;
			return s._moveXYZ;
		}
		// public findRole(rid:string):IRole
		// {let s = this;
		// 	var len:number;
		// 	len = s._sceneRoleVec.length;
		// 	while(--len>-1)
		// 	{
		// 		if(s._sceneRoleVec[len].roleID == rid)
		// 			return s._sceneRoleVec[len]
		// 	}
		// 	return null;
		// }
		/**从a点到b点是否可通行
		 * @param ax 起点x，世界坐标x
		 * @param ay 起点y，世界坐标y
		 * @param bx 终点x，世界坐标x
		 * @param by 终点y，世界坐标y
		 * @param padding 通行范围(像素)，默认0
		 * @param flag 通行标志 默认Barrier.LAND
		*/
		public canLinePass(ax:number,ay:number,bx:number,by:number,padding:number=0,flag:number=Barrier.LAND):boolean
		{
			let s= this;
			let arr:number[] = ghost.PositionUtil.getAToBPosArray(ax, ay, bx, by);
			let i:number,len:number;
			len = arr.length;
			for(i=0;i<len;i+=2)
			{
				if(!s.canPass(arr[i+1],arr[i],flag))
					return false;
			}
			return true;
		}
		/**是否可通行
		 * @param x 世界坐标x
		 * @param y 世界坐标y
		 * @param flag 通行标志 参考Barrier常量 1 陆 2 水 4 空
		*/
		public canPass(x:number,y:number,flag:number = 1):number
		{			
			if(this.ignoreBarrier)
				return Barrier.PASS;
			return this.barrier.barrierState(x,y,flag);
		}
		/**是否可通行(根据格子索引)
		 * @param col 格子列索引
		 * @param row 格子行索引
		 * @param flag 通行标志 参考Barrier常量 默认Barrier.LAND 1 陆 2 水 4 空
		*/
		public canGridPass(col:number,row:number,flag:number = Barrier.LAND):number
		{			
			if(this.ignoreBarrier)
				return Barrier.PASS;
			return this.barrier.barrierGridState(col,row,flag);
		}
		/**是否障碍(根据世界坐标)
		 * @param x
		 * @param y
		 * @param flag 可通行的标志，默认Barrier.LAND
		*/
		public isBarrier(x:number,y:number,flag:number = Barrier.LAND):boolean
		{
			let s= this;
			let toX:number,toY:number;
			let gridSize:number;		
			if(s.ignoreBarrier)return false;								
			gridSize = s.gridSize;
			toX = x / gridSize |0;
			toY = y / gridSize |0;
			return !s.canGridPass(toX,toY,flag);
		}
		public getRoute(stX:number,stY:number,endX:number,endY:number):number[]
		{
			return null;
		}
		public setSceneLogic(logic:ISceneLogicBase)
		{
			let s = this;
			s.sceneLogic = logic;	
			s.sceneLogic.sceneMgr = s;			
		}
		public get mapName():string
		{
			return this._mapName;
		}

		public get mapAreaSize():number
		{
			return this._mapAreaSize;
		}

		public get myPlayer():IMyPlayer
		{
			return this._myPlayer;
		}
		
		/**地图滚动的侦听器*/
		public get mapMoveListener():Listener
		{
			return this._mapMoveListener;
		}
		/**地图重绘的侦听器*/
		public get mapRedrawListener():Listener
		{
			return this._mapRedrawListener;
		}

		public get sceneCfg():any
		{
			return this._sceneCfg;
		}		
		/**地砖平铺最大宽度*/
		public get maxAreaWidth():number
		{
			return this._maxAreaWidth;
		}		
		/**地砖平铺最大高度下的行数*/
		public get maxAreaRow():number
		{
			return Math.ceil(this._maxAreaHeight / this._gridSize);
		}		
		/**地砖平铺最大宽度下的列数*/
		public get maxAreaCol():number
		{
			return Math.ceil(this._maxAreaWidth / this._gridSize);
		}		
		/**地砖平铺最大高度*/
		public get maxAreaHeight():number
		{
			return this._maxAreaHeight;
		}		
		
		public set maxAreaX(value:number)
		{
			this._maxAreaX = value;
		}		
		public set maxAreaY(value:number)
		{
			this._maxAreaY = value;
		}		
		/**X方向尽头区号*/
		public get maxAreaX():number
		{
			return this._maxAreaX;
		}
		/**Y方向尽头区号*/
		public get maxAreaY():number
		{
			return this._maxAreaY;
		}
		public get mapMinX():number
		{
			return this._mapMinX;
		}
		public get mapMinY():number
		{
			return this._mapMinY;
		}
		public get mapMaxX():number
		{
			return this._mapMaxX;			
		}
		public get mapMaxY():number
		{
			return this._mapMaxY;
		}
		// public set mapAreaSize(value:number)
		// {
		// 	this._mapAreaSize = value;
		// }

		public get sceneScale():number
		{
			return this._sceneScale;
		}

		public get sceneHeight():number
		{
			return this._sceneHeight;
		}

		public get sceneWidth():number
		{
			return this._sceneWidth;
		}

		public get mapRight():number
		{
			return this._mapRight;
		}

		public get mapBottom():number
		{
			return this._mapBottom;
		}		
		public keyFocus(): boolean
		{
			return true
		}
        public kDown(keyCode: number): void
		{
			
		}
        public kUp(keyCode: number): void
		{
			
		}
		/**键控方向的判断
		 * @return 返回方向
		*/
		protected keyDirect():number
		{
			let direct:number;
			let s = this;
			let keyBoard:GYKeyboard = GYKeyboard.getInstance();
			if(keyBoard.isKeyDown(Laya.Keyboard.W))
			{
				if(keyBoard.isKeyDown(Laya.Keyboard.D))
					direct = DirectionType.RIGHT_UP;
				else if(keyBoard.isKeyDown(Laya.Keyboard.A))
					direct = DirectionType.LEFT_UP;
				else
					direct = DirectionType.UP;
			}
			else if(keyBoard.isKeyDown(Laya.Keyboard.D))
			{
				if(keyBoard.isKeyDown(Laya.Keyboard.S))
					direct = DirectionType.RIGHT_DOWN;
				else
					direct = DirectionType.RIGHT;
			}
			else if(keyBoard.isKeyDown(Laya.Keyboard.S))
			{
				if(keyBoard.isKeyDown(Laya.Keyboard.A))
					direct = DirectionType.LEFT_DOWN;
				else
					direct = DirectionType.DOWN;
			}
			else if(keyBoard.isKeyDown(Laya.Keyboard.A))
			{
				direct = DirectionType.LEFT;
			}
			else
			{
				direct=-1;				
			}
			return direct;
			
		}
		public pause():boolean
		{
			let s =this;
			if(s._paused)return false;
			s._paused = true;
			s._pauseStartTime = CommonUtil.loopTime;
			return true;
		}
		public resume():boolean
		{
			let s = this;
			if(!s._paused)return false;
			s._paused = false;
			s._pauseTime += CommonUtil.loopTime - s._pauseStartTime;
			return true;
		}
		/**开启场景编辑，编辑时，不可点击寻路*/
		public editable(val:boolean):void
		{
			let s = this;
			if(s._editabled == val)return;
			s._editabled = val;			
			s._sceneTouchabled = !s._editabled;			
		}
		public get editabled():boolean
		{
			return this._editabled;
		}

		private _disposed:boolean;
		public get disposed():boolean
		{
			return this._disposed;
		}
		public dispose():void
		{
			let s = this;
			if(s._disposed)return;
			s._disposed = true;
			s.clearScene();
			GYKeyboard.getInstance().removeKeyListener(this);
		}
		
		// protected _sceneRoleVec:IRole[];
		// protected _delRoleVec:IRole[];
		/**层级刷新数组，请把需要刷新角色层级的角色对象放入次数组*/
		protected _depthArr:IRole[];
		public _runMinX:number;
		public _runMaxX:number;
		public _runMinY:number;
		public _runMaxY:number;
		protected _mapX:number;
		protected _mapY:number;
		protected _mapRight:number;
		protected _mapBottom:number;		
		protected _runRect:Rectangle;
		protected _visibleRect:Rectangle;
		protected _mapMinX:number;
		protected _mapMaxX:number;
		protected _mapMinY:number;
		protected _mapMaxY:number;
		protected _areaArr:any[];
		protected _areaYArr:any[];
		protected _sceneCfg:any;		
		protected _maxAreaX:number;
		protected _maxAreaY:number;
		protected _maxAreaWidth:number;
		protected _maxAreaHeight:number;
		protected _mapWidth:number;
		protected _mapHeight:number;
		protected _mapAreaSize:number;
		protected _gridSize:number;		
		protected _mapName:string;	
		protected _backMapName:string;	
		protected _rateCount:number;	
		protected _backScaleX:number;
		protected _backScaleY:number;		
		protected _brickExt:string;

		protected _myPlayer:IMyPlayer;
		protected _mapMoveListener:Listener;
		
		protected _sceneWidth:number;
		protected _sceneHeight:number;
		protected _sceneBaseWidth:number;
		protected _sceneBaseHeight:number;
		protected _sceneScale:number;
		protected _isScaleChange:boolean;
		protected _gameContainer:GYSprite;
		protected _sceneLayer:GYSprite;
		
		protected _targetScale:number;
		protected _scaleStep:number;
		protected _scaleTime:number;
		protected _scaleKeepTime:number;
		protected _scaleDir:number;
		protected _initMapX:number;
		protected _initMapY:number;
		protected _sceneName:string;
		protected _mapPW:number;
		protected _mapPH:number;
		protected _mapPCol:number;
		protected _mapPRow:number;
		// protected _sceneRoleStsDict:any;
		protected _resKey:string;

		protected _mapBricker:MapBricker;
		protected _mapBackBricker:MapBricker;
		protected _touchMapX:number;
		protected _touchMapY:number;
		protected _touchDrag:boolean;
		protected _touchTarget:any;
		public _editabled:boolean;
		protected _sceneTouchabled:boolean;
		protected _lastTick:number;
		protected _yIndexTime:number;

		protected _default:map2D.Default;

		
		public aStar:AStar;
		public barrier:Barrier;
		public timeTick:number;
	}
}